package com.example;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import android.view.Gravity;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class CrashHandler implements UncaughtExceptionHandler {
    public final static String versionTag = "";
    private final String TAG = "CrashHandler";
    private UncaughtExceptionHandler mDefaultHandler;
    private static CrashHandler INSTANCE;
    private Context mContext;
    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
    private Map<String, String> infos = new HashMap<String, String>();
    private String crashDir = "/crash/";
//    private ExceptionLogModel exceptionEntity = new ExceptionLogModel();

    private CrashHandler() {
    }

    public static CrashHandler getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new CrashHandler();
        }
        return INSTANCE;
    }

    public void init(Context ctx, String dir) {
        mContext = ctx;
        crashDir = dir;
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        if (!handleException(ex) && mDefaultHandler != null) {
            mDefaultHandler.uncaughtException(thread, ex);
        } else {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                Log.e(TAG, "error : ", e);
            }
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(0);
//            Intent intent = new Intent(mContext, LuancherActivity.class);
//            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
//                    Intent.FLAG_ACTIVITY_NEW_TASK);
//            mContext.startActivity(intent);

//            Intent intent = new Intent(mContext.getApplicationContext(), LuancherActivity.class);
//            PendingIntent restartIntent = PendingIntent.getActivity(
//                    mContext.getApplicationContext(), 0, intent,
//                    Intent.FLAG_ACTIVITY_NEW_TASK);
//            //退出程序
//            AlarmManager mgr = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
//            mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000,
//                    restartIntent); // 1秒钟后重启应用
        }
    }

    private boolean handleException(final Throwable ex) {
        Log.e(TAG, "handleException : ", ex);
        if (ex == null) {
            return true;
        }

        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                Toast toast = Toast.makeText(mContext, "程序开个小差，正在退出", Toast.LENGTH_LONG);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();

                collectDeviceInfo(mContext);

                saveCrashInfo2File(ex);

                Looper.loop();
            }
        }.start();

        return true;
    }


    private String saveCrashInfo2File(Throwable ex) {

        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> entry : infos.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            sb.append(key + "=" + value + "\n");
        }

        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        ex.printStackTrace(printWriter);
        Throwable cause = ex.getCause();
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.close();
        String result = writer.toString();
        sb.append(result);
        Log.e(TAG, "异常退出错误：" + sb.toString());
        try {
            long timestamp = System.currentTimeMillis();
            DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = formatter.format(new Date());
            // start 添加错误日志到数据库
//            exceptionEntity.setReportTime((int) (System.currentTimeMillis())+"");
//            exceptionEntity.setReportText(result);
//            // 网络连接状态(0:未连接, 1:已连接, 2:未检测到)
//            exceptionEntity.setNetConnected(AppUtils.isNetworkAvailable(mContext) ? "1" : "0");
//            exceptionEntity.setNetType(getNetworkType(mContext));
//            CrashUtils.getDao().addLogToSdCard("程序崩溃：\n"+exceptionEntity.toString());
//            String UserIdOrPhoneNumber = "userId="+ UserDataManager.getDao().getUserId()+
//                    "phoneNumber="+UserDataManager.getDao().getUserPhoneNumber();
//            Log.e("程序崩溃",exceptionEntity.toString());
//            CrashUtils.getInstance().netSubmitLog(AiyigeExceptionModel.type_app_crash,"程序崩溃：\n"+result,AiyigeExceptionModel.rating_4);
            // end 添加错误日志到数据库
            String fileName = "crash-" + time + "-" + timestamp + ".log";
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                String path = Environment.getExternalStorageDirectory() + crashDir;
                File dir = new File(path);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                FileOutputStream fos = new FileOutputStream(path + fileName);
                fos.write(result.getBytes());
                fos.close();
            }
            return fileName;
        } catch (Exception e) {
            Log.e(TAG, "an error occured while writing file...", e);
        }
        return null;
    }


    public void collectDeviceInfo(Context ctx) {
        try {
            PackageManager pm = ctx.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
            if (pi != null) {
                String versionName = pi.versionName == null ? "null" : pi.versionName;
                String versionCode = pi.versionCode + "";
                infos.put("versionName", versionName);
                infos.put("versionCode", versionCode);
            }
        } catch (NameNotFoundException e) {
            Log.e(TAG, "an error occured when collect package info", e);
        }
        Field[] fields = Build.class.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                infos.put(field.getName(), field.get(null).toString());
                Log.d(TAG, field.getName() + " : " + field.get(null));
            } catch (Exception e) {
                Log.e(TAG, "an error occured when collect crash info", e);
            }
        }
    }


//    public static String getNetworkType(Context context) {
//        String strNetworkType = "";
//        ConnectivityManager cm = (ConnectivityManager) context
//                .getSystemService(Context.CONNECTIVITY_SERVICE);
//        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
//        if (networkInfo != null && networkInfo.isConnected()) {
//            if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
//                strNetworkType = "WIFI";
//            } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
//                String _strSubTypeName = networkInfo.getSubtypeName();
//
//                // TD-SCDMA networkType is 17
//                int networkType = networkInfo.getSubtype();
//                switch (networkType) {
//                    case TelephonyManager.NETWORK_TYPE_GPRS:
//                    case TelephonyManager.NETWORK_TYPE_EDGE:
//                    case TelephonyManager.NETWORK_TYPE_CDMA:
//                    case TelephonyManager.NETWORK_TYPE_1xRTT:
//                    case TelephonyManager.NETWORK_TYPE_IDEN: // api<8 : replace by
//                        // 11
//                        strNetworkType = "2G";
//                        break;
//                    case TelephonyManager.NETWORK_TYPE_UMTS:
//                    case TelephonyManager.NETWORK_TYPE_EVDO_0:
//                    case TelephonyManager.NETWORK_TYPE_EVDO_A:
//                    case TelephonyManager.NETWORK_TYPE_HSDPA:
//                    case TelephonyManager.NETWORK_TYPE_HSUPA:
//                    case TelephonyManager.NETWORK_TYPE_HSPA:
//                    case TelephonyManager.NETWORK_TYPE_EVDO_B: // api<9 : replace by
//                        // 14
//                    case TelephonyManager.NETWORK_TYPE_EHRPD: // api<11 : replace by
//                        // 12
//                    case TelephonyManager.NETWORK_TYPE_HSPAP: // api<13 : replace by
//                        // 15
//                        strNetworkType = "3G";
//                        break;
//                    case TelephonyManager.NETWORK_TYPE_LTE: // api<11 : replace by
//                        // 13
//                        strNetworkType = "4G";
//                        break;
//                    default:
//                        // http://baike.baidu.com/item/TD-SCDMA 中国移动 联通 电信 三种3G制式
//                        if (_strSubTypeName.equalsIgnoreCase("TD-SCDMA")
//                                || _strSubTypeName.equalsIgnoreCase("WCDMA")
//                                || _strSubTypeName.equalsIgnoreCase("CDMA2000")) {
//                            strNetworkType = "3G";
//                        } else {
//                            strNetworkType = _strSubTypeName;
//                        }
//
//                        break;
//                }
//            }
//        }
//        return strNetworkType;
//    }


}
